import { Button, DatePicker, Form, Loading, Select, Switch, Tab } from '@alifd/next';
import { useRequest } from 'ahooks';
import { isNil, uniq } from 'lodash-es';
import moment from 'moment';
import React from 'react';
import './App.scss';
import CountryMap from './components/CountryMap';
import { IProvinceGDP } from './core/interface';
import PieChart from './components/PieChart';
import LineChartForGDP from './components/LineChartForGDP';
import HealthChart from './components/HealthChart';
import LineChartForGDPAndEmployee from './components/LineChartForGDPAndEmployee';
import LineChartForBirthAndDeathRate from './components/LineChartForBirthAndDeathRate';
import DeathAndHealthChart from './components/DeathAndHealthChart/DeathAndHealthChart';
import BubbleChart from './components/BubbleChart/BubbleChart';
import StackBarChart from './components/StackBarChart';

const MaxYear = 2013;
const MinYear = 1952;

function App() {
  const [year, setYear] = React.useState<number>(2008);
  const [province, setProvince] = React.useState('北京');
  const [autoPlay, setAutoPlay] = React.useState(false);
  const timerRef = React.useRef<number>();

  const { data, loading } = useRequest(async () => {
    const res = await fetch('public/ChinaData.csv');
    const csvStrings = await res.text();
    const list: IProvinceGDP[] = [];
    if (!csvStrings) return list;
    csvStrings.split(/[\r\n+]/).forEach((line: string, rowNumber: number) => {
      line = line?.trim() ?? '';
      if (!!line && rowNumber !== 0) {
        let valueList = line.split(',');
        if (valueList.length !== 12) {
          valueList = valueList.concat(Array.from(Array(12 - valueList.length)).map(() => ''));
        }
        const gdpObject: IProvinceGDP = {
          year: parseInt(valueList[0], 10),
          province: (valueList[1] ?? '').replace(/省|壮族自治区|自治区|维吾尔自治区|回族自治区|自治区|市/g, ''),
          gdp: parseFloat(valueList[2] || '0'),
          gdp1: parseFloat(valueList[3] || '0'),
          gdp2: parseFloat(valueList[4] || '0'),
          gdp3: parseFloat(valueList[5] || '0'),
          employedPersonNumber: parseFloat(valueList[6] || '0'),
          healthInstitutions: parseInt(valueList[7] || '0', 10),
          population: parseFloat(valueList[8] || '0'),
          birthRate: parseFloat(valueList[9] || '0'),
          deathRate: parseFloat(valueList[10] || '0'),
          naturalGrowthRate: parseFloat(valueList[11] || '0'),
        };
        list.push(gdpObject);
      }
    });
    return list;
  });
  const yearlyData = React.useMemo(() => {
    if (isNil(data) || !data?.length) return [];
    return data.filter(item => item.year === year);
  }, [data, year]);
  const provinces = React.useMemo<string[]>(() => {
    return uniq((yearlyData ?? []).map(item => item.province));
  }, [yearlyData]);

  const getCurrentYear = () => year;

  const startInterval = () => {
    timerRef.current = setInterval(() => {
      setYear((_year) => _year >= MaxYear ? MinYear : _year + 1);
    }, 1000);
  };

  React.useEffect(() => {
    if (autoPlay) {
      startInterval();
    } else {
      !!timerRef.current && clearInterval(timerRef.current);
    }
    return () => {
      !!timerRef.current && clearInterval(timerRef.current);
    }
  }, [autoPlay]);

  return (
    <div className="page-container">
      <div className="filter">
        <Form inline>
          <Form.Item label="当前年份">
            <DatePicker.YearPicker
              value={moment().year(year)}
              onChange={(v: moment.Moment) => {
                setAutoPlay(false);
                setYear(v.year());
              }}
              disabledDate={(date: moment.Moment) => {
                return date.year() < 1952 || date.year() > 2013;
              }}
              hasClear={false}
            />
          </Form.Item>
          <Form.Item label="自动播放">
            <Switch
              checked={autoPlay}
              onChange={v => setAutoPlay(v)}
            />
          </Form.Item>

          {!!province && (
            <Form.Item label="当前选中省份：">
              <Select
                value={province}
                onChange={v => setProvince(v)}
                dataSource={provinces}
              />
            </Form.Item>
          )}
        </Form>
      </div>
      <div className="charts-container">
        <Loading visible={loading} inline={false}>
          <Tab shape="wrapped" size="medium">
            <Tab.Item title="GDP统计">
              <div className="province-charts-container">
                <CountryMap
                  year={year}
                  currentProvince={province}
                  yearData={yearlyData}
                  changeCurrentProvince={setProvince}
                />
                <div className="chart-by-province">
                  {!!province && (
                    <PieChart
                      year={year}
                      currentData={(data ?? []).find(item => item.year === year && item.province === province)}
                      currentProvince={province}
                    />
                  )}
                  {!!province && (
                    <LineChartForGDP
                      currentData={(data ?? []).filter(item => item.province === province).sort((a, b) => a.year - b.year)}
                      currentProvince={province}
                    />
                  )}
                </div>
              </div>
              <BubbleChart
                year={year}
                yearlyData={yearlyData}
              />
              <StackBarChart
                year={year}
                yearlyData={yearlyData}
              />
            </Tab.Item>
            <Tab.Item title="健康设施统计">
              <div className="yearly-charts-container">
                <CountryMap
                  year={year}
                  currentProvince={province}
                  yearData={yearlyData}
                  changeCurrentProvince={setProvince}
                  seriesData={(yearlyData ?? []).map(item => ({
                    name: item.province,
                    value: item.healthInstitutions,
                    data: item,
                  }))}
                  title="各省健康设施分布图"
                  style={{
                    width: '50%',
                    height: '100%',
                  }}
                />
                <HealthChart
                  year={year}
                  yearlyData={yearlyData}
                />
              </div>
            </Tab.Item>
            <Tab.Item title="就业人数统计">
              <div className="yearly-charts-container">
                <CountryMap
                  year={year}
                  currentProvince={province}
                  yearData={yearlyData}
                  changeCurrentProvince={setProvince}
                  seriesData={(yearlyData ?? []).map(item => ({
                    name: item.province,
                    value: item.employedPersonNumber,
                    data: item,
                  }))}
                  title="各省就业人数统计图"
                  style={{
                    width: '100%',
                    height: '400px',
                    borderBottom: '1px solid #C4C6CF',
                  }}
                />
                {!!province && (
                  <LineChartForGDPAndEmployee
                    currentData={(data ?? []).filter(item => item.province === province).sort((a, b) => a.year - b.year)}
                    currentProvince={province}
                  />
                )}
              </div>
            </Tab.Item>
            <Tab.Item title="出生、死亡、增长率统计">
              <div className="yearly-charts-container">
                {!!province && (
                  <LineChartForBirthAndDeathRate
                    currentData={(data ?? []).filter(item => item.province === province).sort((a, b) => a.year - b.year)}
                    currentProvince={province}
                  />
                )}
                {!!province && (
                  <DeathAndHealthChart
                    province={province}
                    yearlyData={yearlyData}
                  />
                )}
              </div>
            </Tab.Item>
          </Tab>
        </Loading>
      </div>
    </div>
  )
}

export default App
